home *** CD-ROM | disk | FTP | other *** search
/ Plug-In Power Pack for Netscape Communicator / Plug-In Power Pack for Netscape Communicator.iso / plugins / dataviews / include / vupixrep.h < prev    next >
Text File  |  1997-05-08  |  25KB  |  721 lines

  1. /* 
  2.   static char SccsId[]="@(#)VUpixrep.h    V1.10    3/16/95";
  3. */
  4. /*
  5. |    file name -- VUpixrep.h
  6. |===================================================================
  7. |
  8. |                      V.I. Corporation
  9. |                       Copyright (c) 1991
  10. |
  11. |     VUpixrep.h - structures and macros for use with pixreps
  12. |
  13. |       Chris Hoffmann --- 10 Oct 1991
  14. |
  15. |===================================================================
  16. |
  17. |    Module description/function:
  18. | This module defines the pixrep structure as well as macros for
  19. | examining color components of a pixrep's pixel values. It also defines
  20. | a structure based on a pixrep called a pixscan. A pixscan contains
  21. | the necessary information to read a pixrep as a consecutive stream of
  22. | pixel values. A set of macros are provided to allow this reading to be
  23. | done easily.
  24. | PIXREPS
  25. | A pixrep is an abstract representation of pixel-based graphic data.
  26. | The pixels are considered to be arranged in a rectangular array,
  27. | however, there is quite a bit of flexibility in the actual layout of
  28. | the pixels in the array and in what how the actual pixel values are
  29. | interpreted. The hope is that the pixrep format is general enough to
  30. | be a superset of most raster/pixel formats we must deal with.
  31. | A set of macros are provided to make it easy to read through the
  32. | pixels in a pixrep regardless of its internal format. There are also
  33. | functions for modifying a pixrep in various ways.
  34. | The layout of the actual pixel data array is controlled by certain 
  35. | fields in the pixrep. What follows is a description of the allowable
  36. | variations in the layout. See the actual structure for the names of 
  37. | the fields that control each attribute.
  38. |
  39. | First the pixrep must indicate the height and width of the data in
  40. | pixels. The pixels are given as a single vector of data. The pixels 
  41. | in this vector are arranged in rows,  in left-to-right order. 
  42. | The data can be arranged so the bottom row of the picture is
  43. | first in the array (this is the VI row order) or the top row is the 
  44. | first (this is the order used by X and SunView). Each pixel in the row takes
  45. | up a certain number of bits. This number can be 1, 2, 4, 8, 16, or 32.
  46. | Generally, if the actual depth of the picture is less than the number of
  47. | bits per pixel, the data is stored in the least significant part of
  48. | those bits (for example, if the picture has depth 1 but for some
  49. | reason we were using a byte for each pixel, the low-order bit of
  50. | the byte contains the pixel value). See the description of
  51. | "direct-color" pixreps for exceptions to this. 
  52. | Rows can be aligned on 8, 16 or 32 bit boundaries. If on 8-bit
  53. | boundaries, rows are consecutive in memory. If on 16-bit, each row
  54. | starts on the next even address after the last byte of the previous
  55. | row. Similar is the 32-bit case, where rows start on the first address
  56. | divisible by 4 after the last unused byte.
  57. | If the there are fewer than 8 bits per pixel, the data is packed into
  58. | an 8, 16, or 32 bit unit. Within a unit, the pixels can be entered
  59. | into either the least-significant or the most-signficant bytes of the
  60. | unit first.  Additionally, within each byte of the unit, the pixels
  61. | can be packed in in MSB or LSB order. If the pack unit is 8, the unit
  62. | packing order is irrelevant.
  63. | To help make this packing order business clearer, suppose the start of
  64. | the first row in a 1-bit picture looks like the following:
  65. | 0011 0111 0000 1101 1100 1010 1001 1000     (spaces added for clarity)
  66. | Here is how this pattern would be represented in the first two bytes
  67. | of a few 1-bit deep pixreps with various formats:
  68. | pack-unit = 8,  pack_msf_in_byte = YES, pack_msf_in_unit = either.
  69. | 0x370D 0xCA98
  70. | pack-unit = 8,  pack_msf_in_byte = NO,  pack_msf_in_unit = either.
  71. | 0xCE0B 0x3591       (this is X's bitmap format)
  72. | pack-unit = 16, pack_msf_in_byte = YES, pack_msf_in_unit = YES.
  73. | 0x370D 0xCA98       (this is SunView 680x0 bitmap format)
  74. | pack-unit = 16, pack_msf_in_byte = YES, pack_msf_in_unit = NO.
  75. | 0x0D37 0x98CA    
  76. | pack-unit = 16, pack_msf_in_byte = NO,  pack_msf_in_unit = NO.
  77. | 0xB0EC 0x1953       (this is SunView I386 bitmap format)
  78. | pack-unit = 16, pack_msf_in_byte = NO,  pack_msf_in_unit = YES.
  79. | 0xECB0 0x5319       
  80. | pack-unit = 32, pack_msf_in_byte = YES, pack_msf_in_unit = YES.
  81. | 0x370D 0xCA98
  82. | pack-unit = 8,  pack_msf_in_byte = NO,  pack_msf_in_unit = NO.
  83. | 0x1953 0xBEOC
  84. |
  85. | A row is always an integral multiple of the pack unit long. When
  86. | determining the number of bytes per row, first figure the size by
  87. | finding the number of pack units required, then add additional bytes
  88. | as necessary to satisfy the row alignment.
  89. |
  90. | Unused bits between
  91. | the end of one row and the start of the next may have any value. If
  92. | there are more than 8 bits per pixel, the byte order in each pixel is
  93. | the native order.
  94. | There are two possible formats for the pixel values: they may be
  95. | either "indirect-color" or "direct-color". Indirect-color pixel values
  96. | are indices into a color table; direct-color store actual
  97. | red/green/blue component values.
  98. | If a pixrep points to a color table, the pixel values must be
  99. | indirect-color. Since a color table has at most 256 entries, the depth
  100. | of the pixrep can't be greater than 8. A pixrep can optionally contain
  101. | a pointer to a boolean vector (of length 256) indicating which colors
  102. | in the color table are actually used by the pixrep. Knowing this can
  103. | potentially speed up some pixrep operations, particularly converting
  104. | pixreps to rasters.
  105. | If the color table pointer field is NULL, the pixrep must be
  106. | direct-color. In this case there are three masks indicating where each
  107. | component color is stored in a pixel. Components may be located
  108. | anywhere in the pixel, but each component must occupy consecutive
  109. | bits.  For example, in a typical 24-bit color system each pixel is
  110. | 32-bits long, where the most-significant byte is unused, the next byte
  111. | contains red intensity, the third byte the green and the last byte the
  112. | blue. This layout would be indicated by having a red mask of
  113. | 0x00FF0000, a green mask of 0x00FF00, and a blue mask of 0x000000FF.
  114. | For efficiency's sake, a pixrep also stores where the right-most "1"
  115. | bit of each mask is located.
  116. | PIXSCANS
  117. | Pixscans are an easy way to access pixels in a pixrep. Using a
  118. | pixscan, pixels from a pixrep can be read and written, in either row or
  119. | column order, as a continuous stream of pixels. The current location
  120. | in the pixrep can be changed at any time. A pixrep can be shared by
  121. | any number of pixscans all reading and writing to different portions
  122. | of the pixrep.
  123. |
  124. |    
  125. |    
  126. | ------------------------------------------------------------------
  127. |   Module contents:
  128. |   Macro Name               Description
  129. |   -------------       -------------------------------
  130. |   GETREDPXRP        Get the red component from a direct-color pixel value
  131. |   GETGRNPXRP        "   "   green       "
  132. |   GETBLUPXRP        "   "   blue        "
  133. |   PUTREDPXRP        Put the red component into a direct-color pixel value
  134. |   PUTGRNPXRP        "   "   green       "
  135. |   PUTBLUPXRP        "   "   blue        "
  136. |   PIXPXRP        Create a pixel value from all three components
  137. |   PIXSCALE        Scale component to different range
  138. |   GETREDSTD         Get the red component from a VI standard 24-bit pixel
  139. |   GETGRNSTD         "   "   green       "
  140. |   GETBLUSTD         "   "   blue        "
  141. |   PUTREDSTD         Put the red component into a VI standard 24-bit pixel
  142. |   PUTGRNSTD         "   "   green       "
  143. |   PUTBLUSTD         "   "   blue        "
  144. |   PIXSTD         Create a standard pixel value from all three components
  145. |   ISPIXSTD        Is the pixel value in standard VI format?
  146. |
  147. |   PXSCANPOINT        Make a given pixel the next pixel to be read
  148. |   PXSCANREAD        Read the current pixel and advance pixscan pointer
  149. |   PXSCANWRITE        Write to the current pixel and advance pointer
  150. |   PXSCANREADL        Read in left-to-right, bottom-to-top order
  151. |   PXSCANREADR        Read in right-to-left, top-to-bottom order
  152. |   PXSCANREADD        Read in top-to-bottom, left-to-right order
  153. |   PXSCANREADU        Read in bottom-to-top, left-to-right order
  154. |   PXSCANWRITER        Write in left-to-right, bottom-to-top order
  155. |   PXSCANWRITER        Write in right-to-left, top-to-bottom order
  156. |   PXSCANWRITED        Write in top-to-bottom, left-to-right order
  157. |   PXSCANWRITEU        Write in bottom-to-top, left-to-right order
  158. |   
  159. |====================================================================
  160. */
  161. #ifndef VIPXRP
  162. #define VIPXRP
  163. #include "std.h"
  164. #include "dvstd.h"
  165.  
  166. /*  Module Include Files:  */
  167.  
  168. #include "std.h"
  169. #include "dvstd.h"
  170. #include "dverrors.h"
  171.  
  172.  
  173.  
  174. /*  Module Structure Definitions:  */
  175.  
  176. /* the actual pixrep structure typedef is in the file dvstd.h */
  177.  
  178. #if 0        
  179.         
  180. typedef struct
  181.   {
  182.   int width, height;        /* width and height in pixels */
  183.   UBYTE depth;            /* number of bits of color information */
  184.   UBYTE bits_per_pixel;        /* 1,2,4,8,16,32 bits */
  185.   UBYTE row_alignment;        /* 8,16,32==Rows aligned on char,short,LONG */
  186.   DV_BOOL  origin_at_ll;        /* is origin in lower-left? */
  187.   UBYTE pack_unit;        /* if bits/pixel < 8, packing unit */
  188.   DV_BOOL  pack_msf_in_byte;    /* if bits/pixel < 8, order of pixels in byte */
  189.   DV_BOOL  pack_msf_in_unit;    /* if bits/pixel < 8, order of bytes in unit */
  190.   LONG   pixels_length;        /* length of pixel array */
  191.   UBYTE *pixels;        /* actual pixels */
  192.   /* if (pclut != NULL), pixels are index into color table (*pclut) */
  193.   COLOR_TABLE *pclut;
  194.   DV_BOOL *color_used;        /* which colors actually used (if known) */
  195.   /* if (pclut == NULL), pixels are direct color: */
  196.   ULONG red_mask;        
  197.   int   red_shift;        
  198.   ULONG grn_mask;        /* For green component of pixel, calculate */
  199.   int   grn_shift;        /* ((pixel & grn_mask) >> grn_shift)       */
  200.   ULONG blu_mask;        
  201.   int   blu_shift;        /* & similarly for red and blue components */
  202.   } PIXREP;
  203.  
  204. #endif 
  205.  
  206. /* enum for function VUpxFlip() */
  207. typedef enum
  208.   {
  209.   V_PX_HORIZONTAL,        /* flip over horizontal axis */
  210.   V_PX_VERTICAL            /* flip over vertical axis */
  211.   } V_PX_FLIP_ENUM;
  212.  
  213. /* enum for function VUpxMerge() */
  214. typedef enum
  215.   {
  216.   V_PX_COPY,            /* copy source to target */
  217.   V_PX_AND,            /* and source and target */
  218.   V_PX_OR,            /* or source and target */
  219.   V_PX_XOR            /* xor source and target */
  220.   } V_PX_MERGEMODE_ENUM;
  221.  
  222. /*------------------------ pixrep pixel macros ---------------------------- */
  223. /*
  224.  | Macros for getting color information from direct-color pixreps.
  225.  | In all cases, the colors are in the scale of the pixrep. That is,
  226.  | if the red component is 3 bits wide, then the component values
  227.  | must be in the range 0..7.
  228.  |
  229.  |   Arguments:
  230.  |    pix            -- a pixel value read from a pixrep
  231.  |    pr            -- the pixrep that the pixel was read from
  232.  */
  233. #define GETREDPXRP( pix, pr )  (((pix) & (pr).red_mask) >> (pr).red_shift)
  234. #define GETGRNPXRP( pix, pr )  (((pix) & (pr).grn_mask) >> (pr).grn_shift)
  235. #define GETBLUPXRP( pix, pr )  (((pix) & (pr).blu_mask) >> (pr).blu_shift)
  236.  
  237. #define PUTREDPXRP( pix, r, pr ) ( ( (pix) & ~(pr).red_mask ) | \
  238.                    ( ((r) << (pr).red_shift) & (pr).red_mask) )
  239. #define PUTGRNPXRP( pix, g, pr ) ( ( (pix) & ~(pr).grn_mask ) | \
  240.                    ( ((g) << (pr).grn_shift) & (pr).grn_mask) )
  241. #define PUTBLUPXRP( pix, b, pr ) ( ( (pix) & ~(pr).blu_mask ) | \
  242.                    ( ((b) << (pr).blu_shift) & (pr).blu_mask) )
  243.  
  244. /*
  245.  | Macro to build a pixrep pixel value from the three color components.
  246.  | Again, the red, green, blue components must be already scaled
  247.  |   Arguments:
  248.  |    r, g, b            -- color components to use when creating pixel
  249.  |    pr            -- the pixrep defining the pixel format
  250.  */
  251. #define PIXPXRP( r, g, b, pr ) ((((r) << (pr).red_shift) & (pr).red_mask) | \
  252.                   (((g) << (pr).grn_shift) & (pr).grn_mask) | \
  253.                   (((b) << (pr).blu_shift) & (pr).blu_mask) )
  254.  
  255. #define PIXSCALE( p, bs, bt ) (((bs)==(bt)) ? \
  256.                          (p) : \
  257.                          ((bs)>(bt)) ? \
  258.                                ((p)>>((bs)-(bt))) : \
  259.                                (((p)<<((bt)-(bs))) + \
  260.                                      ((1<<((bt)-((bs)+1)))-1) \
  261.                         ) \
  262.                    )
  263.  
  264. /* macros for performing the equivalent actions on a pixel in "standard" 
  265. |  24-bit RGB format.
  266. */
  267. #define GETREDSTD( p )  ( ((p) & 0xFF0000) >> 16)
  268. #define GETGRNSTD( p )  ( ((p) & 0x00FF00) >>  8)
  269. #define GETBLUSTD( p )  ( ((p) & 0x0000FF)      )
  270. #define PUTREDSTD( p, r ) ( ((p) & 0x00FFFF) | (((r) << 16) & 0xFF0000) )
  271. #define PUTGRNSTD( p, g ) ( ((p) & 0xFF00FF) | (((g) <<  8) & 0x00FF00) )
  272. #define PUTBLUSTD( p, b ) ( ((p) & 0xFFFF00) | (((r)      ) & 0x0000FF) )
  273. #define PIXSTD( r, g, b ) ( (((r) << 16) & 0xFF0000) | \
  274.                 (((g) <<  8) & 0x00FF00) | \
  275.                 (((r)      ) & 0x0000FF) | \
  276.                 0x1000000 )
  277. /* determines whether a pixel value is in standard format */
  278. #define ISPIXSTD( p ) ( (p) & 0x1000000 )
  279.  
  280. /*------------------------ pixscan macros ---------------------------- */
  281. /*
  282. |    These macros are used to efficiently read pixels, in order, from
  283. |    a pixrep. To do this two "private" structures are needed: a
  284. |    "pixscan" and a "pixptr". 
  285. |
  286. |       The following types hold for all the macros:
  287. |    pxrp       is a PIXREP. Not a pointer to a PIXREP, but a PIXREP.
  288. |            If all you have is a PIXREP ptr, dereference it
  289. |            with "*".
  290. |
  291. |    pxscan        is a PIXSCAN. Not a pointer to a PIXSCAN.
  292. |
  293. |    pixptr        is a PIXPTR. You may want to declare this
  294. |            a register variable.
  295. |
  296. |    source_pixel, target_pixel    are ULONG
  297. |
  298. |    Macros:
  299. |       -------
  300. |    PXSCANPOINT(pxrp, pxscan, pixptr, x, y) 
  301. |    PXSCANREAD(target_pixel, pxrp, pxscan, pixptr ) 
  302. |    PXSCANWRITE( pxrp, pxscan, pixptr, source_pixel ) 
  303. |    PXSCANREADL(target_pixel, pxrp, pxscan, pixptr ) 
  304. |    PXSCANREADR(target_pixel, pxrp, pxscan, pixptr ) 
  305. |    PXSCANREADD(target_pixel, pxrp, pxscan, pixptr ) 
  306. |    PXSCANREADU(target_pixel, pxrp, pxscan, pixptr ) 
  307. |    PXSCANWRITEL( pxrp, pxscan, pixptr, source_pixel ) 
  308. |    PXSCANWRITER( pxrp, pxscan, pixptr, source_pixel ) 
  309. |    PXSCANWRITED( pxrp, pxscan, pixptr, source_pixel ) 
  310. |    PXSCANWRITEU( pxrp, pxscan, pixptr, source_pixel ) 
  311. |
  312. |    To initialize a pixscan, call VUpxScanInit.
  313. |    The pixscan is pointing at pixel (0,0). That is, that is the 
  314. |    first pixel that will be read. Rows can be numbered either
  315. |    in with origin at lower-left (row 0 is bottom row) or upper-right
  316. |       (row 0 is top row).
  317. |
  318. |    To point the pixscan at some other pixel, use PXSCANPOINT.
  319. |    Remember that the order the rows are numbered depends on
  320. |    what row-order you specified when you created the pixscan.
  321. |
  322. |    Read a pixel with PXSCANREAD. The value of the current pixel
  323. |    is put in target_pixel and the pixscan is set to point to the next 
  324. |    pixel to the right. At the end of a row, the pixscan is set to point at
  325. |    the left-most pixel of the next-higher-numbered row (upwards if
  326. |       origin in lower-left, downwards otherwise).
  327. |
  328. |    Write a pixel value with PXSCANWRITE. source_pixel is written at the
  329. |    current point in the pixscan and the pointer is adjusted as
  330. |    in PXSCANREAD. 
  331. |
  332. |    PXSCANREADL reads the pixscan in left to right, increasing row
  333. |        order (the same order as PXSCANREAD).
  334. |    PXSCANREADR reads the pixscan right to left, increasing row order
  335. |    PXSCANREADU reads the pixscan decreasing row, left to right col
  336. |        order ("DOWN" a column instead of ACROSS a row)
  337. |    PXSCANREADD reads the pixscan increasing row, left to right col
  338. |        order ("UP" a column instead of ACROSS a row)
  339. |
  340. |    Similarly for PXSCANWRITE{L,R,U,D}
  341. |
  342. |
  343. */
  344.  
  345. #define PXSCANREADL(target_pixel, pxrp, pxscan, pixptr ) PXSCANREAD(target_pixel, pxrp, pxscan, pixptr )
  346. #define PXSCANREAD(target_pixel, pxrp, pxscan, pixptr ) \
  347. do \
  348. { \
  349.   if ((pxscan).iCol == (pxrp).width) \
  350.     { \
  351.     PXSCANROWS(pxrp, pxscan, pixptr) \
  352.     } \
  353.   switch ((pxrp).bits_per_pixel) \
  354.     { \
  355.   case 32: \
  356.     (target_pixel) = *(pixptr).pul++; \
  357.     break; \
  358.   case 16: \
  359.     (target_pixel) = (unsigned short)*((pixptr).pus++); \
  360.     break; \
  361.   case 8: \
  362.     (target_pixel) = (UBYTE)*((pixptr).pub++); \
  363.     break; \
  364.   default: \
  365.     (target_pixel) = (*(pixptr).pub >> (pxscan).shift_array[(pxscan).bit_offset]) & (pxscan).read_mask; \
  366.     PXSCANBITI( pxrp, pxscan, pixptr ) \
  367.     } \
  368.   (pxscan).iCol += 1; \
  369. } \
  370. while(0)
  371.  
  372. #define  PXSCANWRITEL( pxrp, pxscan, pixptr, source_pixel ) PXSCANWRITE( pxrp, pxscan, pixptr, source_pixel )
  373. #define  PXSCANWRITE( pxrp, pxscan, pixptr, source_pixel ) \
  374. do \
  375. { \
  376.   if ((pxscan).iCol == (pxrp).width) \
  377.     { \
  378.     PXSCANROWS(pxrp, pxscan, pixptr) \
  379.     } \
  380.   switch ((pxrp).bits_per_pixel) \
  381.     { \
  382.   case 32: \
  383.     *(pixptr).pul++ = source_pixel; \
  384.     break; \
  385.   case 16: \
  386.     *(pixptr).pus++ = (unsigned short)source_pixel; \
  387.     break; \
  388.   case 8: \
  389.     *(pixptr).pub++ = (UBYTE)source_pixel; \
  390.     break; \
  391.   default: \
  392.     *(pixptr).pub &= ~(pxscan).mask_array[(pxscan).bit_offset] ; \
  393.     *(pixptr).pub |= ((UBYTE)source_pixel << (pxscan).shift_array[(pxscan).bit_offset]) ; \
  394.     PXSCANBITI( pxrp, pxscan, pixptr ) \
  395.     break; \
  396.     } \
  397.     (pxscan).iCol += 1; \
  398. } \
  399. while(0)
  400.  
  401. #define PXSCANREADR(target_pixel, pxrp, pxscan, pixptr ) \
  402. do \
  403. { \
  404.   if ((pxscan).iCol < 0) \
  405.     { \
  406.     (pxscan).iCol = (pxrp).width-1; \
  407.     (pxscan).iRow += 1; \
  408.     PXSCANPOINT( pxrp, pxscan, pixptr, (pxscan).iCol, (pxscan).iRow ); \
  409.     } \
  410.   switch ((pxrp).bits_per_pixel) \
  411.     { \
  412.   case 32: \
  413.     (target_pixel) = *(pixptr).pul--; \
  414.     break; \
  415.   case 16: \
  416.     (target_pixel) = (unsigned short)*((pixptr).pus--); \
  417.     break; \
  418.   case 8: \
  419.     (target_pixel) = (UBYTE)*((pixptr).pub--); \
  420.     break; \
  421.   default: \
  422.     (target_pixel) = (*(pixptr).pub >> (pxscan).shift_array[(pxscan).bit_offset]) & (pxscan).read_mask; \
  423.      PXSCANBITD( pxrp, pxscan, pixptr ) \
  424.     } \
  425.   (pxscan).iCol -= 1; \
  426. } \
  427. while(0)
  428.  
  429. #define  PXSCANWRITER( pxrp, pxscan, pixptr, source_pixel ) \
  430. do \
  431. { \
  432.   if ((pxscan).iCol < 0) \
  433.     { \
  434.     (pxscan).iCol = (pxrp).width-1; \
  435.     (pxscan).iRow += 1; \
  436.     PXSCANPOINT( pxrp, pxscan, pixptr, (pxscan).iCol, (pxscan).iRow ); \
  437.     } \
  438.   switch ((pxrp).bits_per_pixel) \
  439.     { \
  440.   case 32: \
  441.     *(pixptr).pul-- = source_pixel; \
  442.     break; \
  443.   case 16: \
  444.     *(pixptr).pus-- = (unsigned short)source_pixel; \
  445.     break; \
  446.   case 8: \
  447.     *(pixptr).pub-- = (UBYTE)source_pixel; \
  448.     break; \
  449.   default: \
  450.     *(pixptr).pub &= ~(pxscan).mask_array[(pxscan).bit_offset] ; \
  451.     *(pixptr).pub |= ((UBYTE)source_pixel << (pxscan).shift_array[(pxscan).bit_offset]) ; \
  452.     PXSCANBITD( pxrp, pxscan, pixptr ) \
  453.     } \
  454.     (pxscan).iCol -= 1; \
  455. } \
  456. while(0)
  457.  
  458. #define PXSCANREADD(target_pixel, pxrp, pxscan, pixptr ) \
  459. do \
  460. { \
  461.   if ((pxscan).iRow < 0) \
  462.     { \
  463.     (pxscan).iRow  = (pxrp).height-1; \
  464.     PXSCANCOLI( pxrp, pxscan, pixptr ) \
  465.     } \
  466.   PXSCANRD(target_pixel, pxrp, pxscan, pixptr ) \
  467.   (pxscan).iRow -= 1; \
  468.   if ((pxscan).rows_increase) \
  469.     (pixptr).pub -= (pxscan).bytes_per_row; \
  470.   else \
  471.     (pixptr).pub += (pxscan).bytes_per_row; \
  472. } \
  473. while(0)
  474.  
  475. #define PXSCANWRITED(pxrp, pxscan, pixptr, source_pixel ) \
  476. do \
  477. { \
  478.   if ((pxscan).iRow < 0) \
  479.     { \
  480.     (pxscan).iRow  = (pxrp).height-1; \
  481.     PXSCANCOLI( pxrp, pxscan, pixptr ) \
  482.     } \
  483.   PXSCANWR(pxrp, pxscan, pixptr, source_pixel ) \
  484.     (pxscan).iRow -= 1; \
  485.   if ((pxscan).rows_increase) \
  486.     (pixptr).pub -= (pxscan).bytes_per_row; \
  487.   else \
  488.     (pixptr).pub += (pxscan).bytes_per_row; \
  489. } \
  490. while(0)
  491.  
  492. #define PXSCANREADU(target_pixel, pxrp, pxscan, pixptr ) \
  493. do \
  494. { \
  495.   if ((pxscan).iRow >= (pxrp).height) \
  496.     { \
  497.     (pxscan).iRow  = 0; \
  498.     PXSCANCOLI( pxrp, pxscan, pixptr ) \
  499.     } \
  500.   PXSCANRD(target_pixel, pxrp, pxscan, pixptr ) \
  501.   (pxscan).iRow += 1; \
  502.   if ((pxscan).rows_increase) \
  503.     (pixptr).pub += (pxscan).bytes_per_row; \
  504.   else \
  505.     (pixptr).pub -= (pxscan).bytes_per_row; \
  506. } \
  507. while(0)
  508.  
  509. #define PXSCANWRITEU(pxrp, pxscan, pixptr, source_pixel ) \
  510. do \
  511. { \
  512.   if ((pxscan).iRow >= (pxrp).height) \
  513.     { \
  514.     (pxscan).iRow  = 0; \
  515.     PXSCANCOLI( pxrp, pxscan, pixptr ) \
  516.     } \
  517.   PXSCANWR(pxrp, pxscan, pixptr, source_pixel ) \
  518.   (pxscan).iRow += 1; \
  519.   if ((pxscan).rows_increase) \
  520.     (pixptr).pub += (pxscan).bytes_per_row; \
  521.   else \
  522.     (pixptr).pub -= (pxscan).bytes_per_row; \
  523. } \
  524. while(0)
  525.  
  526. #define PXSCANPOINT(pxrp, pxscan, pixptr, x, y)  \
  527. do \
  528.   {  \
  529.   UBYTE *qxy_prow;  \
  530.   int qxy_ppb;  \
  531.     \
  532.   if ((pxscan).rows_increase)  \
  533.     qxy_prow = (pxrp).pixels + ((pxscan).bytes_per_row * (y));  \
  534.   else  \
  535.     qxy_prow = (pxrp).pixels +  \
  536.       ((pxscan).bytes_per_row * ((pxrp).height - ((y)+1)));  \
  537.   switch ((pxrp).bits_per_pixel)  \
  538.     {  \
  539.   case 32:  \
  540.     (pixptr).pul = ((ULONG*)qxy_prow + (x));  \
  541.     break;  \
  542.   case 16:  \
  543.     (pixptr).pus = ((unsigned short*)qxy_prow + (x));  \
  544.     break;  \
  545.   case 8:  \
  546.     (pixptr).pub = (UBYTE*)qxy_prow + (x);  \
  547.     break;  \
  548.   default:  \
  549.     qxy_ppb =  (x) * (pxrp).bits_per_pixel;  \
  550.     qxy_prow += ((pxrp).pack_unit/8) * (qxy_ppb / (pxrp).pack_unit); \
  551.     qxy_ppb %= (pxrp).pack_unit; \
  552.     (pxscan).unit_offset = qxy_ppb / 8; \
  553.     (pxscan).bit_offset = qxy_ppb % 8; \
  554.     if ((pxscan).always_increasing) \
  555.       (pixptr).pub = qxy_prow + (pxscan).unit_offset; \
  556.     else \
  557.       (pixptr).pub = qxy_prow + (pxscan).max_unit_offset - (pxscan).unit_offset; \
  558.     break;  \
  559.     }  \
  560.   (pxscan).iCol = x;  \
  561.   (pxscan).iRow = y;  \
  562.   (pxscan).colstart = (pixptr).pub;  \
  563.   } \
  564. while(0)  
  565.  
  566. /**************************************************************************/
  567. /**************************************************************************/
  568. /********************** VI internal definitions ***************************/
  569. /**************************************************************************/
  570. /**************************************************************************/
  571.  
  572. #define PXSCANBITI( pxrp, pxscan, pixptr )  \
  573. {  \
  574.   (pxscan).bit_offset += (pxrp).bits_per_pixel;  \
  575.   if ((pxscan).bit_offset > 7) \
  576.     { \
  577.     (pxscan).bit_offset = 0; \
  578.     if ((pxscan).always_increasing) \
  579.       ++(pixptr).pub; \
  580.     else \
  581.       if ((pxscan).unit_offset++ < (pxscan).max_unit_offset) \
  582.     --(pixptr).pub; \
  583.       else \
  584.     { \
  585.     (pxscan).unit_offset = 0; \
  586.     (pixptr).pub += (pxscan).unit_step; \
  587.     } \
  588.       } \
  589.  
  590. #define PXSCANBITD( pxrp, pxscan, pixptr )  \
  591. {  \
  592.   (pxscan).bit_offset -= (pxrp).bits_per_pixel;  \
  593.   if ((pxscan).bit_offset < 0) \
  594.     { \
  595.     (pxscan).bit_offset = (pxscan).max_bit_offset; \
  596.     if ((pxscan).always_increasing) \
  597.       --(pixptr).pub; \
  598.     else \
  599.       if ((pxscan).unit_offset-- < 0) \
  600.     ++(pixptr).pub; \
  601.       else \
  602.     { \
  603.     (pxscan).unit_offset = (pxscan).max_bit_offset; \
  604.     (pixptr).pub -= (pxscan).unit_step; \
  605.     } \
  606.       } \
  607. }
  608.  
  609. #define PXSCANWR(pxrp, pxscan, pixptr, source_pixel) \
  610.   switch ((pxrp).bits_per_pixel) \
  611.     { \
  612.   case 32: \
  613.     *(pixptr).pul = source_pixel; \
  614.     break; \
  615.   case 16: \
  616.     *(pixptr).pus = (unsigned short)source_pixel; \
  617.     break; \
  618.   case 8: \
  619.     *(pixptr).pub = (UBYTE)source_pixel; \
  620.     break; \
  621.   default: \
  622.     *(pixptr).pub &= ~(pxscan).mask_array[(pxscan).bit_offset] ; \
  623.     *(pixptr).pub |= ((UBYTE)source_pixel << (pxscan).shift_array[(pxscan).bit_offset]) ; \
  624.     break; \
  625.     } 
  626.  
  627. #define PXSCANRD(target_pixel, pxrp, pxscan, pixptr) \
  628.   switch ((pxrp).bits_per_pixel) \
  629.     { \
  630.   case 32: \
  631.     (target_pixel) = *(pixptr).pul; \
  632.     break; \
  633.   case 16: \
  634.     (target_pixel) = (unsigned short)*(pixptr).pus; \
  635.     break; \
  636.   case 8: \
  637.     (target_pixel) = (UBYTE)*(pixptr).pub; \
  638.     break; \
  639.   default: \
  640.     (target_pixel) = (*(pixptr).pub >> (pxscan).shift_array[(pxscan).bit_offset]) & (pxscan).read_mask; \
  641.     break; \
  642.     } 
  643.  
  644. #define PXSCANCOLI(pxrp, pxscan, pixptr) \
  645.   (pxscan).iCol += 1; \
  646.   (pixptr).pub = (pxscan).colstart; \
  647.   switch ((pxrp).bits_per_pixel) \
  648.     { \
  649.   case 32: \
  650.     ++(pixptr).pul; \
  651.     break; \
  652.   case 16: \
  653.     ++(pixptr).pus; \
  654.     break; \
  655.   case 8: \
  656.     ++(pixptr).pub; \
  657.     break; \
  658.   default: \
  659.     PXSCANBITI(pxrp, pxscan, pixptr) \
  660.     break; \
  661.     } \
  662.   (pxscan).colstart = (pixptr).pub;
  663.  
  664. #define PXSCANROWS(pxrp, pxscan, pixptr) \
  665.     (pxscan).iCol = 0;  \
  666.     (pxscan).iRow += 1;  \
  667.     (pxscan).bit_offset = 0;  \
  668.     (pxscan).unit_offset = 0;  \
  669.     if ((pxscan).rows_increase) \
  670.       (pixptr).pub = (pxrp).pixels + (pxscan).iRow *  \
  671.     (pxscan).bytes_per_row;  \
  672.     else  \
  673.       (pixptr).pub = (pxrp).pixels +  \
  674.     ((pxrp).height - ((pxscan).iRow+1)) * (pxscan).bytes_per_row;  \
  675.     (pixptr).pub += (pxscan).max_unit_offset; 
  676.  
  677.  
  678. /* "private" structures */
  679.  
  680. typedef struct
  681.   {
  682.   UBYTE mask_array[8];
  683.   UBYTE shift_array[8];
  684.   UBYTE read_mask;
  685.   int iCol, iRow;
  686.   int bytes_per_row;
  687.   int bit_offset;
  688.   int max_bit_offset;
  689.   int unit_offset;
  690.   int max_unit_offset;
  691.   int unit_step;
  692.   DV_BOOL always_increasing;
  693.   DV_BOOL rows_increase;
  694.   UBYTE *colstart;
  695.   } PIXSCAN;
  696.  
  697. typedef union
  698.   {
  699.   UBYTE  *pub;
  700.   unsigned short *pus;
  701.   ULONG  *pul;
  702.   } PIXPTR;
  703.  
  704.  
  705.  
  706.  
  707. #endif /* VIPXRP */
  708.